import {handleTree} from "@/utils/tree";
import {post, get, request} from "@/utils/http/httpUtils";
import {exportExcel} from "@/utils/ExcelUtil";
import VXETable from "vxe-table";
import {error} from "@/utils/msg";
import {groupAndCompute} from "@/utils/groupCompute";
import {mapActions, mapGetters} from "vuex";
import {axios} from "@/utils/http/httpUtil";

export const DefaultMethods = {
    computed: {
        ...mapGetters('tableData', {getVxeData: 'getData'}),
    },
    destroyed() {
        this.setVxeDataSource({k: this.tableConfig.id, v: ''})
    },
    methods: {
        ...mapActions('tableData', {setVxeDataSource: 'setData'}),
        /**
         * 内置批量删除方法
         * @param o
         * @returns {Promise<void>}
         */ batchRemove() {
            this.confirm("您选中" + this.getSelectRows().length + '条数据，删除后不可恢复，您确定要删除吗？', '删除提示', 'error').then(type => {
                if (type != "cancel") {
                    let list = [];
                    for (let r of this.getSelectRows()) {
                        let p = JSON.parse(JSON.stringify(this.deleteParameter));
                        delete p['$parentId'];
                        for (let key of Object.keys(p)) {
                            p[key] = r[key];
                        }
                        list.push(p);
                    }
                    this.loading['batchDelete'] = true
                    post(this.http, '/online/crud/batchDelete', {
                        parentId: this.deleteParameter['$parentId'], list: list
                    }).then(r => {
                        if (r != false) {
                            this.query();
                        }
                    }).finally(() => {
                        this.loading['batchDelete'] = false
                    });
                }
            })


        }, /**
         * 内置重置方法
         * @param o
         * @returns {Promise<void>}
         */ resetQuery() {
            for (let k of Object.keys(this.table.formConfig.data)) {
                this.table.formConfig.data[k] = undefined
            }
            for (let k of Object.keys(this.parameter)) {
                this.parameter[k] = undefined
            }
            this.initDefaultValue();
            this.query();
        }, /**
         * 内置根据参数查询
         * @param o
         * @returns {Promise<void>}
         */
        queryParams(parameter) {
            if (parameter) {
                Object.assign(this.parameter, parameter)
            }
            return this.query();
        }, /**
         * 内置查询
         * @param o
         * @returns {Promise<void>}
         */
        query() {
            let url = this.tableConfig.definitionSql == 2 ? this.tableConfig.api : '/online/crud/query';
            //分组
            if (this.tableConfig.paging == 2) {
                let method = 'POST';
                if (this.tableConfig.definitionSql != 2) {
                    url += 'Flux';
                }else{
                    method = this.tableConfig.requestType == '1' ? 'POST' : 'GET'
                }
                this.doFetchData(url, method)
            } else {
                let axios = undefined;
                if (this.tableConfig.definitionSql == 2) {
                    if (this.tableConfig.requestType == '1') {
                        axios = post(this.http, url, this.getParams(), false, false);
                    } else {
                        axios = get(this.http, url, this.getParams(), false);
                    }
                } else {
                    axios = post(this.http, url, this.getParams(), false, false);
                }
                this.doQuery(axios);
            }
        },
        doFetchData(url, method) {
            let then = this;
            async function fetchData() {
                then.table.loading = true;
                then.table.loadingConfig.text = "正在查询数据...";
                let headers = then.http.axios().defaults.headers;
                headers['Content-Type'] = 'application/json'
                const response = await fetch(then.http.getBaseURL() + url, {
                    method: method,
                    headers,
                    body: JSON.stringify(then.getParams())
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                then.table.loadingConfig.text = "数据查询完毕，正在传输中...";
                const reader = response.body.getReader();
                const decoder = new TextDecoder('utf-8');
                let buffer = '';
                let done = false;
                while (!done) {
                    const {value, done: doneReading} = await reader.read();
                    done = doneReading;
                    if (value) {
                        const chunk = decoder.decode(value, {stream: !done});
                        buffer += chunk;
                        // 尝试解析可能完整的 JSON 对象
                        while (buffer.includes('}{')) {
                            const index = buffer.indexOf('}{');
                            buffer = buffer.slice(index + 1);
                        }
                    }
                }
                then.setVxeDataSource({k: then.tableConfig.id, v: buffer})
                then.doGroupAndCompute()
                then.table.loading = false;
            }

            fetchData().catch(error => {
                then.table.loading = false;
                console.error('Error fetching data:', error);
            });
        },
        doQuery(axios) {
            this.table.loading = true;
            this.loading['select'] = true
            axios.then(({data, code, msg}) => {
                if (code != 200 && code != 0) {
                    error(msg)
                    return
                }
                let respData = (data instanceof Array) ? data : data.listData;
                if (this.table.treeConfig) {
                    //id , parentId , children
                    respData = handleTree(respData, this.table.treeConfig.treeId, this.table.treeConfig.treeParentId);
                }
                this.table.data = respData;
                this.pagination.total = data.count;
            }).finally(() => {
                this.table.loading = false;
                this.loading['select'] = false
            });
        },

        /**
         * 内置删除方法
         * @param o
         * @returns {Promise<void>}
         */
        remove(o) {
            let {row} = o;
            this.confirm('数据删除后不可恢复，您确定要删除吗？', '删除提示', 'error').then(type => {
                if (type != "cancel") {
                    let params = this.deleteParameter;
                    for (let key of Object.keys(this.deleteParameter)) {
                        if (key != '$parentId') {
                            params[key] = row[key];
                        }
                    }
                    post(this.http, '/online/crud/delete', params).then(r => {
                        if (r != false) {
                            this.query()
                        }
                    })
                }
            })

        }, /**
         * 获取查询参数
         * @returns {{enablePage: OTMixinBodyMethods.methods.pagination.enabled, theme: OTMixinBodyMethods.methods.theme, id: OTMixinBodyMethods.methods.uuid}}
         */
        getParams() {
            if (this.tableConfig.definitionSql == 2) {
                let params = JSON.parse(JSON.stringify(this.table.formConfig.data));
                if (params.enablePage) {
                    params.pageNumber = this.pagination.currentPage;
                    params.pageSize = this.pagination.pageSize;
                }
                return {...this.parameter, ...params}
            }
            let params = {
                id: this.uuid, theme: this.theme, enablePage: this.pagination.enabled
            };
            if (params.enablePage) {
                params.pageNumber = this.pagination.currentPage;
                params.pageSize = this.pagination.pageSize;
            }
            let paramsKey = [];
            for (let o of this.table.formConfig.items) {
                let value = this.table.formConfig.data[o.key];
                if (value == undefined || value == '' || (o.itemRender && o.itemRender.name == '$buttons')) {
                    continue
                }
                let key = o.key.replace(/\$/g, '');
                if (o.tableName != undefined && o.tableName != '') {
                    key = o.tableName + '.' + key;
                }
                //文本域
                if (o.itemRender && o.itemRender.name == "textarea" && o.type != "9") {
                    let values = value instanceof Array ? value : value.split("\n");
                    if (values.length != 0) {
                        let queryParameterMapIn = [];
                        for (let v of values) {
                            if (v != undefined && v.toString().trim() != '') {
                                queryParameterMapIn.push(v);
                            }
                        }
                        if (queryParameterMapIn.length != 0) {
                            if (!params['queryParameterMapIn']) {
                                params['queryParameterMapIn'] = {};
                            }
                            params['queryParameterMapIn'][key] = queryParameterMapIn;
                            paramsKey.push(key);
                        } else if (params['queryParameterMapIn']) {
                            delete params['queryParameterMapIn'][key];
                        }
                    }

                } else if (value.toString().trim() != '') {
                    if (!params['queryParameterListAnd']) {
                        params['queryParameterListAnd'] = [];
                    }
                    let values = value instanceof Array ? value : value.split(",");
                    if (o.type == "98") {
                        params['queryParameterListAnd'].push({
                            value: values[0], key: key, type: 5, toDate: o.toDate
                        });
                        params['queryParameterListAnd'].push({
                            value: values[1], key: key, type: 6, toDate: o.toDate
                        });
                        paramsKey.push(key);
                    } else if (!(value instanceof Array)) {
                        let isNumber = o.selectDom == 7;
                        o.value = value;
                        //type 查询类型 默认等于1--> 1：= 2：!=  3: > 4:< 5: >= 6: <= 7:like '%value' 8:like '%value%' 9:like 'value%'
                        //replace(/\$/g, '') 目的解决范围
                        let obj = {
                            value: isNumber ? Number(value) : value, key: key, type: o.type, toDate: o.toDate
                        };
                        params['queryParameterListAnd'].push(obj);
                        paramsKey.push(key);
                    } else {
                        let isNumber = o.selectDom == 7;
                        for (let v of values) {
                            if (!v) {
                                continue;
                            }
                            let obj = {
                                value: isNumber ? Number(v) : v, key: key, type: o.type, toDate: o.toDate
                            };
                            params['queryParameterListAnd'].push(obj);
                            paramsKey.push(key);
                        }
                    }
                }
            }
            for (let key of Object.keys(this.parameter)) {
                let v = this.parameter[key];
                if (paramsKey.indexOf(key) === -1 && v != undefined && v != '') {
                    if (!params['queryParameterListAnd']) {
                        params['queryParameterListAnd'] = [];
                    }
                    params['queryParameterListAnd'].push({
                        key: key, value: v
                    });
                }
            }
            if (this.orderByColumns.length != 0) {
                params['orderBy'] = this.orderByColumns;
            }
            if (this.events['queryBefore']) {
                this.events['queryBefore'](params)
            }
            return params;
        }, /**
         * 导出数据
         * @param columns 自定义导出字段 t_id
         * @param selectData 选择数据: 当前页数据、勾选行数据、全部数据
         * @param name
         */
        exportData({exportParam, cancelEvent}) {
            let {columns, selectData, name} = exportParam
            for (let column of this.table.columns) {
                for (let c of columns) {
                    if (column.field === c.field && column.params) {
                        c.params = column.params;
                    }
                }
            }
            let data = []
            switch (selectData) {
                case '1': // 当前页
                    data = this.$table.getTableData()['visibleData']
                    break
                case '2': // 勾选
                    data = this.getSelectRows()
                    if (!data || data.length == 0) return error('勾选行数据为空！')
                    break
                case '3': // 全部数据
                    this.exportExcelAll(columns, name)
                    break
                default:
                    data = this.$table.getTableData()['visibleData']
                    break
            }
            if (selectData != '3') {
                exportExcel({
                    data: data,
                    name: name,
                    columns: columns,
                    option: {align: this.$table ? this.$table.align : 'center'}
                })
            }
            cancelEvent()
        }, /**
         * 全部数据导出
         * @param fields 自定义导出字段
         * @param name 文件名
         */
        exportExcelAll(columns, name) {
            let params = this.getParams();
            params.enablePage = false;
            if (this.tableConfig.definitionSql == 2) {
                params.pageNumber = 1;
                params.pageSize = 50000;
            }
            let url = this.tableConfig.definitionSql == 2 ? this.tableConfig.api : '/online/crud/query';
            let method = this.tableConfig.definitionSql == 2 ? (this.tableConfig.requestType == '1' ? 'post' : 'get') : 'post'
            request(this.http, {
                url: url, method: method, data: params, timeout: 1000 * 90 * 90
            }, false, false).then(({data}) => {
                let respData = (data instanceof Array) ? data : data.listData;
                exportExcel({
                    data: respData,
                    name: name,
                    columns: columns,
                    option: {align: this.$table ? this.$table.align : 'center'}
                })
            })
        }, /**
         * 内置确认框
         * @param content
         * @param title
         * @param status
         * @returns {Promise<"model"|"mask"|"close"|"confirm"|"cancel"|"exit"|"exist">}
         */
        async confirm(content, title, status) {
            return await VXETable.modal.confirm({
                content: content, title: title, status: status
            })
        }, /**
         * 内置调用方法
         * @param m
         * @param v
         * @param d
         */
        emits({m, v, d}) {
            if (m && this[m]) {
                this[m](v);
            }
            if (d != false) {
                this.customUrl = undefined;
            }
        }, /**
         * 设置工具栏 but
         * @param code 编码
         * @param key 要设置的key
         * @param value 要设置的value
         */
        setToolBtn(code, key, value) {
            for (let toolBtn of this.toolBtn) {
                if (toolBtn.code == code) {
                    toolBtn[key] = value;
                }
            }
        }, /**
         * 获取工具栏 but
         * @param code 编码
         * @param key 要设置的key
         * @param value 要设置的value
         */
        getToolBtn(code) {
            for (let toolBtn of this.toolBtn) {
                if (toolBtn.code == code) {
                    return toolBtn;
                }
            }
        }, /**
         * 设置操作按钮 but
         * @param code 编码
         * @param key 要设置的key
         * @param value 要设置的value
         */
        setOperationBtn(code, key, value) {
            for (let toolBtn of this.operationBtn) {
                if (toolBtn.code == code) {
                    toolBtn[key] = value;
                }
            }
        }, /**
         * 获取选中
         * @returns {*|*[]|*[]}
         */
        getSelectRows() {
            if (this.selectBox == 1) {
                return this.$table.getRadioRecord() ? [this.$table.getRadioRecord()] : []
            } else if (this.selectBox == 2) {
                return this.$table.getCheckboxRecords(true)
            }
        }, doGroupAndCompute() {
            let groupKey = [];
            let comValue = [];
            for (let column of this.table.columns) {
                if (column.visible && column.groupToOtherProp == 1) {
                    groupKey.push(column.field)
                }
                if (column.groupTotalToOtherProp) {
                    comValue.push(column.field + ":" + column.groupTotalToOtherProp)
                }
            }
            let data = this.getVxeData(this.tableConfig.id);
            let data2 = [];
            if (groupKey.length != 0 & comValue.length != 0) {
                data2 = groupAndCompute(groupKey, comValue, data)
                data = [];
            }
            this.table.loadingConfig.text = "正在渲染数据中...";
            this.table.data=data2
            this.$table.reloadData(data2)
            this.$table.updateFooter(data2)
        },
    }
}
